| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- import { listYears } from "@/lib/storage";
- import { getSession } from "@/lib/auth/session";
- import { canAccessBranch } from "@/lib/auth/permissions";
- import {
- withErrorHandling,
- json,
- badRequest,
- unauthorized,
- forbidden,
- } from "@/lib/api/errors";
- import { mapStorageReadError } from "@/lib/api/storageErrors";
- /**
- * GET /api/branches/[branch]/years
- *
- * Happy-path response must remain unchanged:
- * { "branch": "NL01", "years": ["2024", ...] }
- */
- export const GET = withErrorHandling(
- async function GET(request, ctx) {
- const session = await getSession();
- if (!session) {
- throw unauthorized("AUTH_UNAUTHENTICATED", "Unauthorized");
- }
- // Next.js App Router: params are resolved asynchronously.
- const { branch } = await ctx.params;
- // Validate required route params early (client error => 400).
- if (!branch) {
- throw badRequest(
- "VALIDATION_MISSING_PARAM",
- "Missing required route parameter(s)",
- { params: ["branch"] }
- );
- }
- // RBAC: branch users can only access their own branch.
- if (!canAccessBranch(session, branch)) {
- throw forbidden("AUTH_FORBIDDEN_BRANCH", "Forbidden");
- }
- try {
- const years = await listYears(branch);
- return json({ branch, years }, 200);
- } catch (err) {
- // Convert filesystem errors into:
- // - 404 if the requested path does not exist (but NAS root is reachable)
- // - 500 for system-level storage failures
- throw await mapStorageReadError(err, { details: { branch } });
- }
- },
- { logPrefix: "[api/branches/[branch]/years]" }
- );
|